#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import json

from copy import copy
from socketserver import BaseRequestHandler, ThreadingTCPServer
from maze import Maze
from message import MessageCode
from exception import *


class MazeHandler(BaseRequestHandler):
    maze = None

    def init_maze(self):
        self.maze = Maze(10)

    def recv(self):
        try:
            msg = self.request.recv(8192).decode()
            msg = json.loads(msg)
        except ConnectionAbortedError:
            return None
        return msg

    def send(self, msg_num, msg_content, msg_desc=""):
        msg = {
            "num": msg_num,
            "content": msg_content,
            "desc": msg_desc
        }
        msg = json.dumps(msg).encode()
        self.request.send(msg)

    def handle(self):
        print("Got connection from {0}:{1}".format(self.client_address[0], self.client_address[1]))
        while True:
            msg = self.recv()
            if not msg:
                print("Lost connection from {0}:{1}".format(self.client_address[0], self.client_address[1]))
                exit(0)
            elif msg["num"] == MessageCode.Error:
                _msg = "Server收到的消息号为Error"
                self.send(MessageCode.Error, None, _msg)
            elif msg["num"] == MessageCode.Hello:
                _msg = "与Client建立连接，发送初始化的迷宫信息"
                self.init_maze()
                self.send(MessageCode.Maze, self.maze.serialize(), _msg)
            elif msg["num"] == MessageCode.WayPoint:
                path = msg["content"]
                try:
                    _path = copy(path)
                    result = self.maze.if_walk(_path)
                    if result:
                        new_maze = self.maze.walk(path)
                        _msg = "按照路点前进，迷宫更新完成"
                        self.send(MessageCode.Maze, new_maze.serialize(), _msg)
                    else:
                        _msg = "路点不可到达，Client需要重新发送路点"
                        self.send(MessageCode.Error, self.maze.serialize(), _msg)
                except MazeError as e:
                    _msg = str(e)
                    self.send(MessageCode.Error, None, _msg)
            elif msg["num"] == MessageCode.Bye:
                _msg = "收到Client关闭信号，析构迷宫，关闭连接"
                self.maze = None
                print(_msg)
                exit(0)
            else:
                print("不正确的消息号: {}".format(msg["num"]))


if __name__ == '__main__':
    serv = ThreadingTCPServer(('', 20000), MazeHandler)
    print("Server started on 127.0.0.1, port 20000.....")
    serv.serve_forever()
